/*************************************************************************************************************
 * Filename           : bsp_stepMotor.c
 * Description        : Step motor driver function file
*************************************************************************************************************/


/* Includes ------------------------------------------------------------------------------------------------*/
#include "bsp_stepMotor.h"

/* Private typedef -----------------------------------------------------------------------------------------*/
/* Private define ------------------------------------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------------------------------------*/
STEP_MOTOR_InitTypeDef g_stepMotorInit[] = 
{
  {STEP_MOTOR_A1,STEP_MOTOR_A1_PORT,STEP_MOTOR_A1_PIN},  
  {STEP_MOTOR_B1,STEP_MOTOR_B1_PORT,STEP_MOTOR_B1_PIN}, 
  {STEP_MOTOR_C1,STEP_MOTOR_C1_PORT,STEP_MOTOR_C1_PIN}, 
  {STEP_MOTOR_D1,STEP_MOTOR_D1_PORT,STEP_MOTOR_D1_PIN}, 
};
    
static int g_stepMotorNumber = sizeof(g_stepMotorInit) / sizeof(g_stepMotorInit[0]);  
STEP_MOTOR_ControlTypeDef g_stepMotorControl;

/* Private function prototypes -----------------------------------------------------------------------------*/
static void bsp_stepMotorPinLow(STEP_MOTOR_NameTypeDef stepMotorName);
static void bsp_stepMotorPinHigh(STEP_MOTOR_NameTypeDef stepMotorName);

/* Private functions ---------------------------------------------------------------------------------------*/



/*********************************************************************************************************
 * Function Name   : bsp_StepMotorInit
 * Description     : Configure GPIOs connecting with step motor
 * Input Variable  : void 
 * Return Variable : None
**********************************************************************************************************/
void bsp_StepMotorInit(void)
{   
  GPIO_InitTypeDef  GPIO_InitStructure;

  STEP_MOTOR_NameTypeDef stepMotorName;
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); /* Enable PA clock*/

  for(stepMotorName = g_stepMotorInit[0].stepMotorName;stepMotorName < (STEP_MOTOR_NameTypeDef)g_stepMotorNumber;stepMotorName++)
  {    
    GPIO_InitStructure.GPIO_Pin   = g_stepMotorInit[stepMotorName].stepMotorPin;                
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;        /* Push-pull*/
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(g_stepMotorInit[stepMotorName].stepMotorPort, &GPIO_InitStructure);
    bsp_stepMotorPinLow(stepMotorName);
  }
  g_stepMotorControl.preStep = STEP_MOTOR_STEP0;
  g_stepMotorControl.curStep = STEP_MOTOR_STEP0;
  g_stepMotorControl.loopNum = 0;  
  g_stepMotorControl.status  = ELEVATOR_STOPPING;
  g_stepMotorControl.timeCounter = 0;
}


/**********************************************************************************************************
 * Function Name   : bsp_stepMotorPinLow
 * Description     : Set the pin in low level
 * Input Variable  : stepMotorName
 * Return Variable : None
************************************************************************************************************/
static void bsp_stepMotorPinLow(STEP_MOTOR_NameTypeDef stepMotorName)
{
  g_stepMotorInit[stepMotorName].stepMotorPort->BSRR |= (g_stepMotorInit[stepMotorName].stepMotorPin << 16);
  g_stepMotorInit[stepMotorName].stepMotorPort->BSRR &= !g_stepMotorInit[stepMotorName].stepMotorPin ;
}


/************************************************************************************************************
 * Function Name   : bsp_stepMotorPinHigh
 * Description     : Set the pin in High level
 * Input Variable  : stepMotorName
 * Return Variable : None
*************************************************************************************************************/
static void bsp_stepMotorPinHigh(STEP_MOTOR_NameTypeDef stepMotorName)
{
  g_stepMotorInit[stepMotorName].stepMotorPort->BSRR |=   g_stepMotorInit[stepMotorName].stepMotorPin;
  g_stepMotorInit[stepMotorName].stepMotorPort->BSRR &= !(g_stepMotorInit[stepMotorName].stepMotorPin << 16);
}


/************************************************************************************************************
 * Function Name   : bsp_stepMotorUp
 * Description     : Turn on the step motor in direction up
 * Input Variable  : None
 * Return Variable : None
*************************************************************************************************************/
void bsp_stepMotorUp(void)
{
  if (g_stepMotorControl.loopNum > 0)
  {
    switch (g_stepMotorControl.curStep)
    {
      case STEP_MOTOR_STEP0:
          bsp_stepMotorPinHigh(STEP_MOTOR_A1);
          bsp_stepMotorPinLow(STEP_MOTOR_B1);
          bsp_stepMotorPinLow(STEP_MOTOR_C1);
          bsp_stepMotorPinLow(STEP_MOTOR_D1);

          g_stepMotorControl.curStep = STEP_MOTOR_WAIT;
          g_stepMotorControl.preStep = STEP_MOTOR_STEP0;
          break;
      
       case STEP_MOTOR_STEP1:
          bsp_stepMotorPinLow(STEP_MOTOR_A1);
          bsp_stepMotorPinHigh(STEP_MOTOR_B1);
          bsp_stepMotorPinLow(STEP_MOTOR_C1);
          bsp_stepMotorPinLow(STEP_MOTOR_D1);
          g_stepMotorControl.curStep = STEP_MOTOR_WAIT;
          g_stepMotorControl.preStep = STEP_MOTOR_STEP1;
       break;

       case STEP_MOTOR_STEP2:
          bsp_stepMotorPinLow(STEP_MOTOR_A1);
          bsp_stepMotorPinLow(STEP_MOTOR_B1);
          bsp_stepMotorPinHigh(STEP_MOTOR_C1);
          bsp_stepMotorPinLow(STEP_MOTOR_D1);
          g_stepMotorControl.curStep = STEP_MOTOR_WAIT;
          g_stepMotorControl.preStep = STEP_MOTOR_STEP2;
       break;

       case STEP_MOTOR_STEP3:
          bsp_stepMotorPinLow(STEP_MOTOR_A1);
          bsp_stepMotorPinLow(STEP_MOTOR_B1);
          bsp_stepMotorPinLow(STEP_MOTOR_C1);
          bsp_stepMotorPinHigh(STEP_MOTOR_D1);
          g_stepMotorControl.curStep = STEP_MOTOR_WAIT;
          g_stepMotorControl.preStep = STEP_MOTOR_STEP3;
       break;

       case STEP_MOTOR_STEP4:
          bsp_stepMotorPinLow(STEP_MOTOR_A1);
          bsp_stepMotorPinLow(STEP_MOTOR_B1);
          bsp_stepMotorPinLow(STEP_MOTOR_C1);
          bsp_stepMotorPinLow(STEP_MOTOR_D1); 
          if (--g_stepMotorControl.loopNum == 0)
          {
            g_stepMotorControl.status = ELEVATOR_ARRIVAL;
          }
          g_stepMotorControl.curStep = STEP_MOTOR_STEP0;
          g_stepMotorControl.preStep = STEP_MOTOR_STEP0;
       break;

       case STEP_MOTOR_WAIT:
          
       break;
    } /* End of switch (g_stepMotorControl.curStep)               */
  } /* End of if (g_stepMotorControl.loopNum > 0)                 */
}


/**********************************************************************************************************
 * Function Name   : bsp_stepMotorDown
 * Description     : Turn on the step motor in direction down
 * Input Variable  : None
 * Return Variable : None
************************************************************************************************************/
void bsp_stepMotorDown(void)
{
  if (g_stepMotorControl.loopNum > 0)
  {
    switch (g_stepMotorControl.curStep)
    {
      case STEP_MOTOR_STEP0:
          bsp_stepMotorPinLow(STEP_MOTOR_A1);
          bsp_stepMotorPinLow(STEP_MOTOR_B1);
          bsp_stepMotorPinLow(STEP_MOTOR_C1);
          bsp_stepMotorPinHigh(STEP_MOTOR_D1);
         
          g_stepMotorControl.curStep = STEP_MOTOR_WAIT;
          g_stepMotorControl.preStep = STEP_MOTOR_STEP0;
       break;
      
       case STEP_MOTOR_STEP1:
          bsp_stepMotorPinLow(STEP_MOTOR_A1);
          bsp_stepMotorPinLow(STEP_MOTOR_B1);
          bsp_stepMotorPinHigh(STEP_MOTOR_C1);
          bsp_stepMotorPinLow(STEP_MOTOR_D1);
          g_stepMotorControl.curStep = STEP_MOTOR_WAIT;
          g_stepMotorControl.preStep = STEP_MOTOR_STEP1;
       break;

       case STEP_MOTOR_STEP2:
          
          bsp_stepMotorPinLow(STEP_MOTOR_A1);
          bsp_stepMotorPinHigh(STEP_MOTOR_B1);
          bsp_stepMotorPinLow(STEP_MOTOR_C1);
          bsp_stepMotorPinLow(STEP_MOTOR_D1);
          g_stepMotorControl.curStep = STEP_MOTOR_WAIT;
          g_stepMotorControl.preStep = STEP_MOTOR_STEP2;
       break;

       case STEP_MOTOR_STEP3:
          bsp_stepMotorPinHigh(STEP_MOTOR_A1);
          bsp_stepMotorPinLow(STEP_MOTOR_B1);
          bsp_stepMotorPinLow(STEP_MOTOR_C1);
          bsp_stepMotorPinLow(STEP_MOTOR_D1);

          g_stepMotorControl.curStep = STEP_MOTOR_WAIT;
          g_stepMotorControl.preStep = STEP_MOTOR_STEP3;
       break;

       case STEP_MOTOR_STEP4:
          bsp_stepMotorPinLow(STEP_MOTOR_A1);
          bsp_stepMotorPinLow(STEP_MOTOR_B1);
          bsp_stepMotorPinLow(STEP_MOTOR_C1);
          bsp_stepMotorPinLow(STEP_MOTOR_D1); 
          if (--g_stepMotorControl.loopNum == 0)
          {
            g_stepMotorControl.status = ELEVATOR_ARRIVAL;
          }
          g_stepMotorControl.curStep = STEP_MOTOR_STEP0;
          g_stepMotorControl.preStep = STEP_MOTOR_STEP0;
       break;

       case STEP_MOTOR_WAIT:
          
       break;
    } /* End of switch (g_stepMotorControl.curStep)             */
  } /* End of if (g_stepMotorControl.loopNum > 0)                 */
}

/************************************************************************************************************
 * Function Name   : bsp_stepMotorEnable 
 * Description     : Turn on the step motor 
 * Input Variable  : None
 * Return Variable : None
*************************************************************************************************************/
void bsp_stepMotorEnable(void)
{
   g_stepMotorControl.loopNum = FLOOR_MOTOR_ROUND_NUM; 
   g_stepMotorControl.status = ELEVATOR_RUNNING;
}


/************************************************************************************************************
 * Function Name   : bsp_stepMotorDisable
 * Description     : Turn off the step motor 
 * Input Variable  : None
 * Return Variable : None
*************************************************************************************************************/
void bsp_stepMotorDisable(void)
{
   g_stepMotorControl.loopNum = 0; 
   g_stepMotorControl.status  = ELEVATOR_STOPPING;
}


/*************************************************END OF FILE************************************************/




